/**
 * Copyright (c) 2017, Alex. All rights reserved.
 */
package com.oschina.bottle.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.StringUtils;

import java.util.Collection;

/**
 * redis管理
 *
 * @author <a href="mailto:zhongchao@gegejia.com">zhong</a>
 * @version 1.0 2017/9/28
 * @since 1.0
 */
public class ExtendRedisCacheManager extends RedisCacheManager
{
    public final static Logger logger = LoggerFactory.getLogger(ExtendRedisCacheManager.class);

    private static char separator = '#';

    private static String defaultCacheName = "cache";

    public ExtendRedisCacheManager(RedisOperations redisOperations)
    {
        super(redisOperations);
    }

    public ExtendRedisCacheManager(RedisOperations redisOperations, Collection<String> cacheNames)
    {
        super(redisOperations, cacheNames);
    }

    public ExtendRedisCacheManager(RedisOperations redisOperations, Collection<String> cacheNames, boolean cacheNullValues)
    {
        super(redisOperations, cacheNames, cacheNullValues);
    }

    @Override
    public Cache getCache(String name)
    {
        //如果查询不到cache，则根据name生成新的cache
        int index = name.lastIndexOf(separator);
        if(index < 0) {
            return super.getCache(name);
        }

        String cacheName = name.substring(0, index);
        if(StringUtils.isEmpty(cacheName)){
            cacheName = defaultCacheName;
        }

        RedisCache cache = (RedisCache) super.getCache(cacheName);
        if (cache == null) {
            return null;
        }
        // get expiration from name
        Integer expiration = getExpiration(name, index);
        if (expiration == null || expiration < 0) {
            logger.warn("Default expiration time will be used for cache '{}' because cannot parse '{}', cacheName : " + cacheName + ", name : " + name);
            return cache;
        }

        return new RedisCache(cacheName, (isUsePrefix() ? getCachePrefix().prefix(cacheName) : null), getRedisOperations(), expiration);

    }

    private Integer getExpiration(final String name, final int separatorIndex) {
        Integer expiration = null;
        String expirationAsString = name.substring(separatorIndex + 1);
        try {
            expiration = Integer.parseInt(expirationAsString);
        } catch (NumberFormatException ex) {
            logger.error(String.format("Cannnot separate expiration time from cache: '%s'", name), ex);
        }
        return expiration;
    }


}
